﻿using Microsoft.Extensions.DependencyInjection;
using PropertyChanged;
using System;
using VIA.ImageProcessing;
using VIA.Integration;
using VIA.Integration.Automatics;
using VIA.Integration.Domain;

namespace VIA.Project.Domain.Devices
{
    public class VirtualCamera : Automatic, ICamera, IHasOption<VirtualCameraOption>, ISuportInitialization, IVirtualCamera
    {
        public bool IsGrabbing { get; set; }

        public AcquisitionMode AcquisitionMode { get; set; }
        public TriggerMode TriggerMode { get; set; }
        public TriggerSource TriggerSource { get; set; }

        bool _isConnected;
        ImageData _imageDataTemp;
        public bool IsConnected
        {
            get => _isConnected;
            set
            {
                _isConnected = value;
                IsConnectedChanged?.Invoke(this);
            }
        }

        public VirtualCameraOption Option { get; set; } = new();
        public event EventHandler<object> ImageObjectReceived;
        public event EventHandler<ImageReceivedEventArgs> ImageReceived;
        public event Action<ICamera> OnIsGrabChanged;
        public event Action<IDevice> IsConnectedChanged;
        public event EventHandler<CameraIsGrabChangedArgs> IsGrabChanged;

        public void Connect()
        {
            IsConnected = true;
        }

        public void Disconnect()
        {
            IsConnected = false;
        }

        public float GetExposureTime()
        {
            return -1;
        }

        public float GetGain()
        {
            return -1;
        }

        public void SetExposureTime(float exposureTime)
        {

        }

        public void SetGain(float gain)
        {

        }

        public ImageData Snap(int timeOut = -1)
        {
            string str = string.Empty;
            if (Option.IsUseImageFolder)
            {
                if (!Directory.Exists(Option.ImagePath))
                {
                    return null;
                }
                var strs = Directory.GetFiles(Option.ImagePath, "*.png").Union(Directory.GetFiles(Option.ImagePath, "*.bmp")).Union(Directory.GetFiles(Option.ImagePath, "*.jpg")).ToArray();
                if (strs.IsNullOrEmpty())
                    throw new NullReferenceException("图片路径为空");
                Random random = new Random();
                var index = random.Next(strs.Length);
                str = strs[index];
            }
            else
            {
                str = @Option.ImagePath;
            }
            ImageData image = str.IsNullOrEmpty() || !File.Exists(str) ? null : new ImageData(str);
            ImageObjectReceived?.Invoke(this, new ImageReceivedEventArgs(image));
            return image;
        }

        public void SoftTrigger()
        {

        }

        public void StartGrabbing()
        {
            IsGrabbing = true;
        }

        public void StopGrabbing()
        {
            IsGrabbing = false;
        }

        public Task InitializeAsync()
        {
            Option = Service.GetService<ICurrentRecipe>().Get<VirtualCameraOption>(this.Id);
            if (Option == null)
                throw new Exception("Option不可以 为空");
            return Task.CompletedTask;
        }

        public object Snap(int timeout = -1, CancellationToken cancellationToken = default)
        {
            return Snap(-1);
        }

        public Task<ImageData> SnapAsync(bool isSoftwareTrigger, CancellationToken cancellationToken = default, int timeout = -1)
        {
            return Task.Run(() => { return Snap(timeout); });
        }

        public Task<ImageData> SnapAsync(CancellationToken cancellationToken = default, int timeout = -1)
        {
            return Task.Run(() => { return Snap(timeout); });
        }

        public object Snap()
        {
            return Snap(-1);
        }
    }
}
